package com.huike.clues.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huike.clues.domain.*;
import com.huike.clues.mapper.SysUserMapper;
import com.huike.clues.mapper.TbAssignRecordMapper;
import com.huike.clues.mapper.TbClueTrackRecordMapper;
import com.huike.clues.domain.*;
import com.huike.clues.domain.vo.AssignmentVo;
import com.huike.clues.mapper.*;
import com.huike.clues.service.TbActivityService;
import com.huike.clues.service.TbClueService;
import com.huike.clues.mapper.TbClueMapper;
import com.huike.clues.service.TbRulePoolService;
import com.huike.clues.utils.HuiKeCrmDateUtils;
import com.huike.clues.utils.JobUtils;
import com.huike.common.core.domain.entity.SysUserDTO;
import com.huike.common.exception.CustomException;
import com.huike.common.utils.DateUtils;
import com.huike.common.utils.SecurityUtils;
import com.huike.clues.service.TbRulePoolService;
import com.huike.clues.utils.HuiKeCrmDateUtils;
import com.huike.common.annotation.DataScope;
import com.huike.common.constant.Constants;
import com.huike.common.core.domain.entity.SysUserDTO;
import com.huike.common.exception.CustomException;
import com.huike.common.utils.DateUtils;
import com.huike.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.language.bm.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
* @author 93238
* @description 针对表【tb_clue(线索)】的数据库操作Service实现
* @createDate 2023-10-12 06:35:46
*/
@Slf4j
@Service
public class TbClueServiceImpl extends ServiceImpl<TbClueMapper, TbClue> implements TbClueService{
    @Resource
    private TbClueMapper tbClueMapper;

    @Resource
    private TbClueTrackRecordMapper tbClueTrackRecordMapper;

    @Resource
    private TbRulePoolService tbRulePoolService;

    @Resource
    private TbAssignRecordMapper tbAssignRecordMapper;

    @Resource
    private SysUserMapper userMapper;

    @Resource
    TbRulePoolService rulePoolService;

    @Resource
    private TbActivityMapper tbActivityMapper;


    @Override
    public boolean checkCluePhoneExis(String phone) {
        // 验证是否存在这条线索
        TbClue tbClue = tbClueMapper.selectTbClueByPhone(phone);
        if (tbClue == null) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    @Transactional
    public int falseClue(Long id, String reason, String remark) {
        // 根据id查询线索
        TbClue tbClue = tbClueMapper.selectTbClueById(id);
        // 获取当前线索的伪线索失败次数(最大3次)
        int falseCount = tbClue.getFalseCount();
        // 判断是否上报3次，是，该线索被删除，不进入线索池
        if (falseCount >= 2) {
            // 删除这条线索
            return tbClueMapper.removeClueByFalseClue(id);
        }
        // 伪线索失败次数小于3次，则将伪线索失败次数加1，并将状态改为伪线索，并更新状态
        tbClue.setFalseCount(tbClue.getFalseCount() + 1);
        tbClue.setStatus(TbClue.StatusType.FALSE.getValue());
        updateTbClue(tbClue);
        // 设置下次跟进时间为空
        updateStatus(tbClue.getId(), TbClue.StatusType.FALSE.getValue());
        // 设置伪线索的属性
        TbClueTrackRecord trackRecord = new TbClueTrackRecord();
        trackRecord.setCreateBy(SecurityUtils.getUsername());
        trackRecord.setFalseReason(reason);
        trackRecord.setRecord(remark);
        trackRecord.setClueId(String.valueOf(id));
        trackRecord.setType("1");
        trackRecord.setCreateTime(DateUtils.getNowDate());
        // 插入伪线索跟进记录
        return tbClueTrackRecordMapper.insertTbClueTrackRecord(trackRecord);
    }


    @Override
    @DataScope(deptAlias = "r", userAlias = "r")
    public List<TbClue> selectTbClueList(TbClue tbClue) {
        List<TbClue> tbClueList = tbClueMapper.selectTbClueList(tbClue);
        return tbClueList;
    }
    @Override
    public int addClue(TbClue tbClue) {
        tbClue.setCreateTime(DateUtils.getNowDate());
        tbClue.setStatus("1");
        tbClueMapper.addClue(tbClue);

        //创建注册一个新线索 同时要把 注册人信息和分配信息 放入分配记录表中
        TbAssignRecord tbAssignRecord = new TbAssignRecord();
        //设置关联id 关联线索表id
        tbAssignRecord.setAssignId(tbClue.getId());
        //设置所属人用户id 通过SecurityUtils.getUserId()工具抓取
        tbAssignRecord.setUserId(SecurityUtils.getUserId());
        //设置所属人名称 通过SecurityUtils.getUsername()工具抓取
        tbAssignRecord.setUserName(SecurityUtils.getUsername());
        //设置所属人组织 SecurityUtils.getDe   ptId()工具抓取
        tbAssignRecord.setDeptId(SecurityUtils.getDeptId());
        //设置创建时间为当前时间
        tbAssignRecord.setCreateTime(DateUtils.getNowDate());

        //将分配记录表数据传入 新增到数据库
        int rows = tbAssignRecordMapper.insertAssignRecord(tbAssignRecord);

        log.info(String.valueOf(rows));
        return rows;

    }

    @Override
    public Boolean selectTbCluePhone(String phone) {
        TbClue tbClue = tbClueMapper.selectTbCluePhone(phone);
        if (tbClue == null){
            return false;
        }
        return true;
    }

    @Override
    public List<TbClue> pool(TbClue tbClue) {
        List<TbClue> tbClueList = tbClueMapper.pool(tbClue);
        for (TbClue clue : tbClueList) {
            //只要tb_clue表里的活动id不为空
            if (clue.getActivityId() != null){
                //查询活动名称 根据活动id查询
                TbActivity tbActivity = tbActivityMapper.selectTbActivityById(clue.getActivityId());
                //只要查出的数据不为null
                if (tbActivity != null){
                    //设置活动名称
                    clue.setActivityName(tbActivity.getName());
                    clue.setChannel(tbActivity.getChannel());
                }
            }
        }
        return tbClueList;
    }

    @Override
    public void updateClue(TbClue tbClue) {
        tbClue.setUpdateTime(DateUtils.getNowDate());
        tbClueMapper.updateClue(tbClue);
    }

    @Override
    public String assignment(AssignmentVo assignmentVo) {
        TbRulePool rulePool = rulePoolService.selectTbRulePoolByType(Constants.rule_type_clue);

        Long userId = assignmentVo.getUserId();
        Long[] clueIds = assignmentVo.getIds();

        // 统计当前分配人所有线索
        int assignRecords = tbAssignRecordMapper.countAssignCluesByUser(userId);
        if (assignRecords >= rulePool.getMaxNunmber()) {
            throw new CustomException("分配失败！最大保有量(" + rulePool.getMaxNunmber() + ")，剩余可以分配"
                    + (rulePool.getMaxNunmber() - assignRecords) + "条线索");
        }
        for (int i = 0; i < clueIds.length; i++) {
            Long clueId = clueIds[i];
            // 超过最大保有量
            if (assignRecords + i >= rulePool.getMaxNunmber()) {
                // return "超过当前用户最大保有量，部分分配成功";
                throw new CustomException("分配失败！保有量达到上线，最多选择" + rulePool.getMaxNunmber() + "条线索");
            }

            // 从新分配
            updateStatus(clueId, "1"); //待跟进状态
            TbAssignRecord tbAssignRecord = addNewRecord(clueId, userId);
        }
        return "全部分配";
    }

    /**
     * 查询线索管理
     *
     * @param id 线索管理ID
     * @return 线索管理
     */
    @Override
    public TbClue selectTbClueById(Long id) {
        TbClue tbClue = tbClueMapper.selectTbClueById(id);
        if (tbClue != null && tbClue.getActivityId() != null) {
            TbActivity activity = tbActivityMapper.selectTbActivityById(tbClue.getActivityId());
            if (activity != null) {
                tbClue.setActivityInfo(activity.getCode() + ":" + activity.getName() + ":" + activity.getInfo());
            }
        }
        // 查询专派遣信息
        TbAssignRecord assignRecord = tbAssignRecordMapper.selectAssignRecordByAssignId(tbClue.getId(), "0");
        tbClue.setOwner(assignRecord.getUserName());
        tbClue.setOwnerTime(assignRecord.getCreateTime());
        return tbClue;
    }

    @Override
    public String gain(Long[] clueIds, Long userId) {
        // 是否批量捞取
        boolean isBatch = clueIds.length > 1 ? true : false;
        // 获取规则池
        TbRulePool rulePool = tbRulePoolService.selectTbRulePoolByType(TbRulePool.RuleType.CLUES.getValue());
        // 统计当前分配人所有线索的数量
        int asignRecords = tbAssignRecordMapper.countAssignCluesByUser(userId);
        // 如果超过最大保有量,则抛出异常
        if (asignRecords >= rulePool.getMaxNunmber()) {
            throw new CustomException("操作失败,线索保有量达到上限(" + rulePool.getMaxNunmber() + ")，无法再捞取");
        }
        // 遍历要捞取的线索
        for (int i = 0; i < clueIds.length; i++) {
            Long clueId = clueIds[i];

            // 超过最大保有量
            if (asignRecords + i >= rulePool.getMaxNunmber()) {
                throw new CustomException("捞取失败！保有量达到上限，最多还可选择" + (rulePool.getMaxNunmber() - asignRecords) + "条线索");
            }
            // 最近捞取记录
            TbAssignRecord assignRecord = tbAssignRecordMapper.selectAssignRecordByAssignId(clueId,
                    TbAssignRecord.RecordType.CLUES.getValue());
            if (assignRecord != null && assignRecord.getUserId().equals(userId)) {
                Date repeatGetTime = JobUtils.getDate(rulePool.getRepeatGetTime().intValue(), rulePool.getRepeatType(),
                        assignRecord.getCreateTime());
                // 判断当前时间是否早于重复捞取时间
                if (DateUtils.getNowDate().before(repeatGetTime)) {
                    // 如果是批量捞取则跳过当前线索,不是批量捞取则抛异常
                    if (isBatch) {
                        continue;
                    } else {
                        throw new CustomException("捞取失败！需要在 " + DateUtils.dateTimeHm(repeatGetTime) + " 后捞取");
                    }
                }
            }
            // 捞取后设置状态为待跟进
            tbClueMapper.resetNextTimeAndStatus(clueId, TbClue.StatusType.UNFOLLOWED.getValue());
            // 新建分配记录
            TbAssignRecord tbAssignRecord = addNewRecord(clueId, userId);
            // 更新线索的失效时间
            Date endDate = HuiKeCrmDateUtils.getEndDateByRule(tbAssignRecord);
            tbClueMapper.updateClueEndTimeById(clueId, endDate);
        }
        return "全部捞取成功";
    }

    public TbAssignRecord addNewRecord(Long id, Long userId) {
        // 查询是否原本就有分配记录,有则更新保留之前的分配记录为不是最新分配人
        tbAssignRecordMapper.updateLatest(id, TbAssignRecord.RecordType.CLUES.getValue());
        // 再新建分配记录
        TbAssignRecord tbAssignRecord = new TbAssignRecord();
        tbAssignRecord.setAssignId(id);
        SysUserDTO sysUserDTO = userMapper.selectUserById(userId);
        tbAssignRecord.setUserId(userId);
        tbAssignRecord.setDeptId(sysUserDTO.getDeptId());
        tbAssignRecord.setUserName(sysUserDTO.getUserName());
        Date now = DateUtils.getNowDate();
        tbAssignRecord.setCreateTime(now);
        tbAssignRecord.setCreateBy(SecurityUtils.getUsername());
        tbAssignRecord.setType(TbAssignRecord.RecordType.CLUES.getValue());
        tbAssignRecordMapper.insertAssignRecord(tbAssignRecord);
        return tbAssignRecord;
    }

    public int updateTbClue(TbClue tbClue) {
        return tbClueMapper.updateTbClue(tbClue);
    }

    @Transactional
    public int updateStatus(Long clueId, String status) {
        return tbClueMapper.resetNextTimeAndStatus(clueId, status);
    }
}




